﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using GestionNewsLetters.Models.Classes;
using GestionNewsLetters.MailService;

namespace GestionNewsLetters.Models.Dao
{

    /// <summary>
    /// Manage newlsetter emailing
    /// </summary>
    public class MailDao
    {

        /// <summary>
        /// Méthode utilisée pour envoyer une newsletter UNIQUEMENT à l'utilisateur courant
        /// Method used to send a newsletter to the current user ONLY (if an administrator wanna test)
        /// </summary>
        /// <param name="idNewsletter"></param>
        /// <param name="adresseUser"></param>
        /// <param name="server"></param>
        public void SendMail(int idNewsletter, string adresseUser, HttpServerUtilityBase server)
        {
            this.SendMail(true, idNewsletter, adresseUser, server);
        }

        /// <summary>
        /// Méthode utilisée pour envoyer une newsletter à TOUS les abonnés
        /// Method used to send a newsletter to every subscribers (not the admins)
        /// </summary>
        /// <param name="idNewsletter"></param>
        /// <param name="server"></param>
        public void SendMail(int idNewsletter, HttpServerUtilityBase server)
        {
            this.SendMail(false, idNewsletter, "", server);
        }

        /// <summary>
        /// Retourne le statut de la newsletter courant
        /// Returns the current newsletter status (ie number of mails sent/to send)
        /// </summary>
        public Infos GetCurrentNewsletterStatus()
        {
            Infos info;

            //using (InewsletterServiceClient client = new InewsletterServiceClient())
            InewsletterServiceClient client = new InewsletterServiceClient();
            {
                info = client.GetState();
            }
            client.Close();

            return info;
        }

        /// <summary>
        /// Renvoie les infos des 100 newsletters précédentes
        /// Returns stats about the previous 100 newsletter (can be modified in the service)
        /// </summary>
        /// <returns></returns>
        public List<Infos> GetStatitiques()
        {
            List<Infos> infos;

            using (InewsletterServiceClient client = new InewsletterServiceClient())
            {
                infos = client.GetStatistics().ToList<Infos>();
            }

            return infos;
        }
        /// <summary>
        /// Send a newsletter
        /// </summary>
        /// <param name="onlyCurrentUser">true, send only to the current admin, to test. If false, publicate the newsletter (send it to publication list)</param>
        /// <param name="idNewsletter">Newsletter ID</param>
        /// <param name="adresseUser">Adress of the current user (administrator). String.Empty can be used if not needed (ie if onlyCurrentUser=false).</param>
        /// <param name="server">HttpServerUtilityBase</param>
        private void SendMail(bool onlyCurrentUser, int idNewsletter, string adresseUser, HttpServerUtilityBase server)
        {
            //We communicate with the service wich send mails
            //On communique avec le service qui gère l'envoie des mails
            using (InewsletterServiceClient client = new InewsletterServiceClient())
            {
                //Not needed as smtp params are managed by the service
               //SmtpInfos smtpInfos = Helper.GetSmtpInfos();

                //Do we have to move the newsletter in the publicated newsletters folder?
                //Est-ce qu'il faut déplacer la newsletter dans le dossier des newsletters envoyées?
                bool deplacer = false;

                //On doit dabord configurer le serveur SMTP
                //Not needed as smtp params are managed by the service
               //client.Configure(smtpInfos.address, smtpInfos.login, smtpInfos.password, smtpInfos.port, smtpInfos.sender);
               
                //Liste des destinataires
                //Emailing list
                Dictionary<int,string> destinataires = new Dictionary<int,string>();

                //If only the current user has to receive the mail
                //Si seul l'utilisateur courant est destinataire
                if(onlyCurrentUser)
                {
                    //Current user is not in registered in the subscribers database. So it's guid is useless (id here)
                    //l'utilisateur courant n'a pas de guid. Il ne sert qu'a la désinscription.
                    destinataires.Add(0, adresseUser);
                }

                    //If we want to send newsletter to subscribers
                //Si tous les contacts en bdd sont destinataires
                else
                {
                    DbMsEntities dbNewsletter = new DbMsEntities();
                    
                    //We get all emails
                    //On récupère toutes les adresses email de la base de données
                    foreach (AUTEUR contact in dbNewsletter.AUTEURS.ToList<AUTEUR>())
	                {
                        //If the user wants to receive the newsletter
                        //Si le contact veut recevoir la newsletter
                        if(contact.NEWSLETTER)
                            destinataires.Add(contact.ID ,contact.MAIL);
	                }
                    deplacer = true;
                }

                //We get the newsletter content
                //On récupère le contenu et le titre de la newsletter
                NewsletterDao newsletterDao = new NewsletterDao(server, Helper.GetUrlApplication());
                Newsletter newsletter =  newsletterDao.GetNewsletterForPublication(idNewsletter, deplacer);

                //We get infos about the service state (the service can only send one newsletter at a time)
                //On récupère les infos sur l'état du service
                Infos infos = client.GetState();

                //If infos is null, the service is not sending emails
                //Si infos est null, le service n'est pas en train d'envoyer des mails
                if (infos == null)
                {
                    //We call the function wich publicate newsletters
                    //On envoie les infos au service qui génère les mails
                    client.SendMailAsync(destinataires, newsletter.Contenu, newsletter.Title);
                }

                    //service busy
                //Le service est occupé
                else
                {
                    throw new Exception("Le service d'envoi de mail est occupé: " + infos.MailsSent + " mails envoyés sur "
                        + infos.TotalMailsToSend 
                        +". La tâche a commencé il y-a " + DateTime.Now.Subtract(infos.StartingDateTime).TotalMinutes + " minutes"); 
                }
            }

        }
    }
}